package sf.database.jdbc.type;

import sf.tools.IOUtils;

import javax.persistence.PersistenceException;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

/**
 * sqlite 不支持blob类型
 */
public class FileClobType implements TypeHandler<File> {

    public File get(ResultSet rs, String columnName) throws SQLException {
        Object object = rs.getObject(columnName);
        return valueToFile(object);
    }

    public File get(ResultSet rs, int index) throws SQLException {
        Object object = rs.getObject(index);
        return valueToFile(object);
    }

    public File get(CallableStatement rs, int index) throws SQLException {
        Object object = rs.getObject(index);
        return valueToFile(object);
    }

    @Override
    public File get(CallableStatement cs, String parameterName) throws SQLException {
        Object object = cs.getObject(parameterName);
        return valueToFile(object);
    }

    public Object set(PreparedStatement ps, Object obj, int i) throws SQLException {
        File file = (File) obj;
        if (null == obj) {
            ps.setNull(i, getSqlType());
        } else {
            try {
                ps.setCharacterStream(i, IOUtils.getReader(file, (String) null));//这个方法在JDBC4才支持。
            } catch (IOException e) {
                throw new PersistenceException(e);
            }
        }
        return null;
    }

    @Override
    public Object set(CallableStatement cs, Object obj, String parameterName) throws SQLException {
        File file = (File) obj;
        if (null == obj) {
            cs.setNull(parameterName, getSqlType());
        } else {
            try {
                cs.setCharacterStream(parameterName, IOUtils.getReader(file, (String) null));//这个方法在JDBC4才支持。
            } catch (IOException e) {
                throw new PersistenceException(e);
            }
        }
        return null;
    }

    @Override
    public void update(ResultSet rs, String columnLabel, Object value) throws SQLException {
        File file = (File) value;
        try {
            rs.updateCharacterStream(columnLabel, IOUtils.getReader(file, (String) null));//这个方法在JDBC4才支持。
        } catch (IOException e) {
            throw new PersistenceException(e);
        }
    }

    @Override
    public void update(ResultSet rs, int columnIndex, Object value) throws SQLException {
        File file = (File) value;
        try {
            rs.updateCharacterStream(columnIndex, IOUtils.getReader(file, (String) null));//这个方法在JDBC4才支持。
        } catch (IOException e) {
            throw new PersistenceException(e);
        }
    }

    public int getSqlType() {
        return Types.CLOB;
    }

    @Override
    public Class<File> getDefaultJavaType() {
        return File.class;
    }


    public File valueToFile(Object obj) throws SQLException {
        if (obj == null) return null;
        if (obj instanceof String) {
            try {
                File file = File.createTempFile("tmp", ".io");
                IOUtils.saveAsFile(file, (String) obj);
                return file;
            } catch (IOException e) {
                throw new SQLException("Error at save clob to file.", e);
            }
        }
        Clob clob = (Clob) obj;
        Reader reader = clob.getCharacterStream();
        try {
            return IOUtils.saveAsTempFile(reader);
        } catch (IOException e) {
            throw new SQLException("Error at saving Blob to file", e);
        }
    }
}